package com.nn.smart.bus.httpclient;

import org.apache.commons.codec.CharEncoding;
import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.ParseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.io.IOException;
import java.net.URI;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class HttpClientUtils {

    private static final Logger LOGGER = LogManager.getLogger(HttpClientUtils.class);

    private CloseableHttpClient client;

    public HttpClientUtils(HttpClientManagerFactoryBen httpClientBean) {
        try {
            this.client = httpClientBean.getObject();
        } catch (Exception e) {
            LOGGER.error("CloseableHttpClient构建失败", e);
            e.printStackTrace();
        }
    }

    private static ResultDto getResult(CloseableHttpResponse response) {
        String result = null;
        HttpEntity httpEntity = null;
        try {
            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                httpEntity = response.getEntity();
                result = EntityUtils.toString(httpEntity, CharEncoding.UTF_8);
                // 释放连接
                EntityUtils.consumeQuietly(httpEntity);
            } else {
                LOGGER.error("拉取失败,错误编码为：{},错误信息：{}", response.getStatusLine().getStatusCode(), response.getStatusLine().getReasonPhrase());
            }
        } catch (ParseException e) {
            LOGGER.error("getResult方法格式转换异常ParseException");
            e.printStackTrace();
        } catch (IOException e) {
            LOGGER.error("getResult方法IO异常IOException");
            e.printStackTrace();
        } finally {
            EntityUtils.consumeQuietly(httpEntity);
        }
        ResultDto resultDto = new ResultDto();
        resultDto.setResponseStatusCode(response.getStatusLine().getStatusCode());
        resultDto.setResult(result);
        return resultDto;
    }

    /**
     * post json 提交方式
     *
     * @param url
     * @param json
     * @return map
     * @throws KeyStoreException
     * @throws NoSuchAlgorithmException
     * @throws KeyManagementException
     * @throws IOException
     * @throws ClientProtocolException
     */
    public ResultDto postJSON(String url, String json) {
        CloseableHttpResponse response = null;
        try {
            HttpPost httpPost = new HttpPost(url);
            StringEntity stringEntity = new StringEntity(json, CharEncoding.UTF_8);
            stringEntity.setContentEncoding(CharEncoding.UTF_8);
            // 发送json数据需要设置contentType
            stringEntity.setContentType("application/json");
            httpPost.setEntity(stringEntity);
            response = client.execute(httpPost);
            return getResult(response);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * post form 提交方式
     *
     * @param url
     * @param map
     * @return map
     * @throws KeyStoreException
     * @throws NoSuchAlgorithmException
     * @throws KeyManagementException
     * @throws IOException
     * @throws ClientProtocolException
     */
    public ResultDto postForm(String url, Map<String, Object> map) throws ClientProtocolException, IOException {
        HttpPost httpPost = new HttpPost(url);
        httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded");
        List<NameValuePair> formParams = new ArrayList<NameValuePair>();
        for (Map.Entry<String, Object> kv : map.entrySet()) {
            formParams.add(new BasicNameValuePair(kv.getKey(), (String) kv.getValue()));
        }
        HttpEntity entity = new UrlEncodedFormEntity(formParams, CharEncoding.UTF_8);
        httpPost.setEntity(entity);
        return getResult(client.execute(httpPost));
    }

    /**
     * get 提交方式
     *
     * @param url
     * @param headerMap
     * @param paramMap
     * @return
     * @throws KeyManagementException
     * @throws NoSuchAlgorithmException
     * @throws KeyStoreException
     * @throws ClientProtocolException
     * @throws IOException
     */
    public ResultDto get(String url, Map<String, String> headerMap, Map<String, String> paramMap) throws KeyManagementException, NoSuchAlgorithmException, KeyStoreException, ClientProtocolException, IOException {
        HttpGet httpGet = new HttpGet();
        if (headerMap != null) {
            for (String key : headerMap.keySet()) {
                httpGet.setHeader(key, headerMap.get(key));
            }
        }
        List<NameValuePair> formparams = setHttpParams(paramMap);
        String param = URLEncodedUtils.format(formparams, "UTF-8");
        httpGet.setURI(URI.create(url + "?" + param));
        return getResult(client.execute(httpGet));
    }

    /**
     * 设置请求参数
     *
     * @param paramMap
     * @return
     */
    private List<NameValuePair> setHttpParams(Map<String, String> paramMap) {
        List<NameValuePair> formparams = new ArrayList<NameValuePair>();
        if (paramMap != null) {
            Set<Map.Entry<String, String>> set = paramMap.entrySet();
            for (Map.Entry<String, String> entry : set) {
                formparams.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
            }
        }
        return formparams;
    }
}
